package com.teckteam.ptvsystem.model.facade;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;

import com.teckteam.ptvsystem.controller.JourneyPlanException;
import com.teckteam.ptvsystem.model.AbstractStop;
import com.teckteam.ptvsystem.model.DepartureTime;
import com.teckteam.ptvsystem.model.ResultNode;
import com.teckteam.ptvsystem.view.LoadingDialog;

public interface PTVModel
{
   /**
    * Calculate distance in kilometres from two GPS coordinates
    * using the Haversine Formula
    * 
    * Equation reference: http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates
    * @param sLat
    * @param sLon
    * @param dLat
    * @param dLon
    * @return result
    */
   double calculateDistance(String sLat, String sLon, String string,
         String string2);
   
   /**
    * Returns list of routes based on transport type.  See PTVConstants for list of flags.
    */
   ArrayList<String> getAllGroupedRoutes(char flag);
   
   /**
    * Returns list of stop objects based on transport type.  See PTVConstants for list of flags.
    */
   ArrayList<AbstractStop> getAllGroupedStops(char flag);
   
   /**
    * Returns list of all stop objects in the system.  References already been collected in advance
    */
   ArrayList<AbstractStop> getAllStops();
   
   /**
    * Returns list of relevant suburbs present in the system based on stop information.
    */
   ArrayList<String> getAllSuburbs();
   
   /**
    * Get full list of stops based on selected Suburb.  Used for finding all nearby stops within a suburb.
    */
   ArrayList<AbstractStop> getAllSuburbStops(String suburbString);
   
   /**
    * Routine to create a Journey Plan based on form inpupt, and return an ArrayList of ordered results.
    * 
    * @param source Name of originating location
    * @param destination Name of ending location
    * @param time Departure time represented as a string
    * @param sLat Source Latitude
    * @param sLon Source Longitude
    * @param dLat Destination Latitude
    * @param dLon Destination Longitude
    * @return resultList
    * @throws JourneyPlanException 
    */
   ArrayList<ResultNode> getJourneyPlan(String source, String destination,
         String time, String sLat, String sLon, String dLat, String dLon) throws JourneyPlanException;
   
   /**
    * CURRENTLY NOT IMPLEMENTED
    * Get nearest stops based on stop (replaced by stops in suburb)
    */
   HashMap<String, AbstractStop[]> getNearestStops(String name);
   
   /**
    * Get timetable of selected Route based on matching String label (enforced by UI combobox)
    * Reconstructs organised object data back into a format similar to the scraped object.
    */
   LinkedHashMap<String, String[]> getRouteTimetable(String name);
   
   /**
    * Debug version of getting route timetable, using retained scrape object.  Preferred not to use this.
    */
   LinkedHashMap<String, String[]> getRouteTimetableDebug(String name);
   
   /**
    * CURRENTLY NOT IMPLEMENTED
    * 
    * Get departure times of stop
    */
   ArrayList<DepartureTime> getStopTimetable(String name);
   
   /**
    * After initializing the model, load and process all required files into the system.
    * 
    * @return fileLoadCount Number of files loaded.
    * @throws FileNotFoundException 
    */
   int importTimetableFiles() throws FileNotFoundException;
   
   /**
    * Returns false if the timetable system is currently empty.
    */
   boolean isEmpty();
   
   /**
    * Read loaded file from database folder.  (Scraper and program init functionality)
    */
   boolean readTimetable(File loadedFile);
   
   /**
    * Empty the timetable system.
    */
   void refreshTimetable() throws FileNotFoundException;
   
   /**
    * Saves scraped timetable data to a file.
    */
   void saveTimetable(LinkedHashMap<String, String[]> result);

   /**
    * Routine to append timetable information from scraped object data.
    * Developer note: May be removed to have refreshed database reload from saved files instead.
    */
   void updateTimetable(LinkedHashMap<String, String[]> linkedHashMap);
}
